import datetime
import ast
from django.shortcuts import render
from django.shortcuts import HttpResponse,HttpResponseRedirect
from django.contrib import messages
from django.http import JsonResponse
from django.utils import timezone
from django.conf import settings
from django.core.files import File
# Create your views here.
from base.models import RawModel
import json,os,shutil
from django.forms.models import model_to_dict
from django.views.decorators.csrf import csrf_exempt
from base.models import ReportFileModel
from django.apps import apps
import shutil
def get_context(request):
    report = request.POST.get('report_style')
    objects = request.POST.get('objects')
    report_type = request.POST.get('report_type')
    fileds = request.POST.get('fileds', '[]')
    obj_ids = []
    if objects:
        obj_ids = objects.split('、')[:-1]  # 直接处理掉最后一个空元素
    model_path = request.POST.get('model')
    # 获取参数
    parms = {}
    for name, value in request.POST.items():
        if name in ['report_style', 'objects', 'model', 'encoding', 'csrfmiddlewaretoken', 'user_id', 'fileds']:
            continue
        parms[name] = value

    # 安全获取模型类（避免使用eval）

    app_name, model_name = model_path.split('.')
    ModelClass = apps.get_model(app_name, model_name)
    # 获取数据并转换为字典
    items = ModelClass.objects.filter(id__in=obj_ids).all()
    detail_data = []
    for item in items:
        item_dict = model_to_dict(item)
        # 处理日期时间类型（转换为字符串）
        for key, value in item_dict.items():
            if isinstance(value, timezone.datetime):
                item_dict[key] = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, datetime.date):
                item_dict[key] = value.strftime('%Y-%m-%d')
        detail_data.append(item_dict)

    detail_data.extend(ast.literal_eval(fileds))
    # 构造完整数据
    data = {
        "Detail": detail_data,
        "Master":
        # 可以根据实际需求添加主表数据
            {"user_id": request.user.id, "username": request.user.get_username(), **parms}
    }

    context = {
        'report': report,
        'data_json': json.dumps(data, ensure_ascii=False),  # 序列化并保留中文
        'report_name': report.split('/')[-1]
    }
    return context
def print(request):
    context=get_context(request)
    # return JsonResponse(context)
    return render(request, 'report/ReportHome.htm', context)

def printNow(request):
    context=get_context(request)


    return render(request, 'report/ReportPrintNow.htm', context)
def reportDesign(request):
    if request.method=='POST':
        report = request.POST.get('report_style')
        report_name=request.POST.get('report_name')
        context = {
            'report': report,
            'report_name': report_name,
        }
        return render(request, 'report/DesignReport.htm', context)

    else:
        return HttpResponse('未知错误')


def create_report_from_local_file(user_id, model_code, local_file_path,type):
    """
    从本地文件创建ReportFileModel
    :param user_id: 关联的用户ID
    :param model_code: 报表标识（如"base_standardmodel"）
    :param local_file_path: 本地文件绝对路径（如"F:/default_reports/standard.pdf"）
    """
    # 1. 验证本地文件是否存在
    if not os.path.exists(local_file_path):
        raise FileNotFoundError(f"本地文件不存在：{local_file_path}")

    # filename=os.path.basename(local_file_path)

    # 3. 打开本地文件，包装为Django File对象
    # 注意：用with语句确保文件句柄关闭
    with open(local_file_path, "rb") as f:
        # File对象需要2个参数：文件句柄、文件名
        django_file = File(f, name=os.path.basename(local_file_path))

        # 4. 创建ReportFileModel实例
        report = ReportFileModel.objects.create(
            user_id=user_id,
            code=model_code,
            type=type,
            state="1",
            default=True,
            report_file=django_file,  # 传递Django File对象
            report_name=os.path.basename(local_file_path)
        )
    report.report_name=os.path.basename(report.report_file.path)
    report.save()
    # print(f"从本地文件创建报表成功：ID={report.id}，文件路径：{report.report_file.path}")
    return report.report_file.name,report.report_name
def creatNewFile(old_file,new_file_name):
    # 2. 验证原始文件是否存在（避免复制不存在的文件）
    if not os.path.exists(old_file):
        raise FileNotFoundError(f"原始文件不存在：{old_file}")
    # dirname = os.path.dirname(old_file)  # 原始文件所在目录
    filename, ext = os.path.splitext(os.path.basename(old_file))  # 文件名+扩展名拆分

    # 新文件名：原文件名 + "_copy" + 扩展名（如 "test_copy.pdf"）
    new_filename = f"{new_file_name}{ext}"
    # 新文件的绝对路径（与原始文件同目录）
    # new_file = os.path.join(dirname, new_filename)
    new_file=os.path.join(settings.MEDIA_ROOT,'temp',new_filename)
    # 4. 避免新文件已存在（可选：若存在则加数字后缀，如 test_copy_1.pdf）
    count = 1
    while os.path.exists(new_file):
        new_filename = f"{new_filename}_copy_{count}{ext}"
        # new_file = os.path.join(dirname, new_filename)
        new_file=os.path.join(settings.MEDIA_ROOT,'temp',new_filename)
        count += 1

    # 5. 执行复制（用copy2保留文件元数据：修改时间、权限等）
    try:
        shutil.copy2(old_file, new_file)  # 复制文件
        # print(f"文件复制成功！\n原始文件：{old_file}\n新文件：{new_file}")
        return new_file
    except Exception as e:
        return 'cuowu'
def reportCreate(request):
    if request.method=='POST':

        report = request.POST.get('report_style')
        user_id=request.user.id
        model=request.POST.get('model')
        type=request.POST.get('report_type')
        report_name = request.POST.get('report_name')
        if report:
            old_file=os.path.join(settings.MEDIA_ROOT,report)
        else:
            if type == '1':
                url = f"uploads/files/report/0/{model}/simple.grf"
            else:
                url = f"uploads/files/report/0/{model}/children/simple.grf"
            if not os.path.exists(os.path.join(settings.MEDIA_ROOT, url)):
                url = f"uploads/files/report/0/simple.grf"
            old_file = os.path.join(settings.MEDIA_ROOT, url)
        if report_name:
            old_file=creatNewFile(old_file,new_file_name=report_name)
        report_url,report_name=create_report_from_local_file(user_id=user_id,model_code=model,local_file_path=old_file,type=type)



        context = {
            'report': report_url,
            'report_name':report_name

        }


        # 重定向回原页面
        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
        # return render(request, 'report/DesignReport.htm', context)
    else:
        return HttpResponseRedirect('/')


def reportAltName(request):
    if request.method == 'POST':
        # 获取表单提交的参数
        report_style = request.POST.get('report_style')  # 原报表文件名（带路径）
        new_report_name = request.POST.get('report_name', '').strip()
        model = request.POST.get('model')
        report_type = request.POST.get('report_type')
        user_id = request.user.id

        # 校验必要参数
        if not all([report_style, new_report_name, model, report_type]):
            messages.error(request, "缺少必要参数，请重试")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
        if '.' in new_report_name:
            messages.error(request, "新名字有非法字符，不要加后缀名，请重试")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
        # 查询对应的报表记录
        try:
            report_file = ReportFileModel.objects.get(
                user_id=user_id,
                report_file=report_style  # 匹配原文件路径
            )
        except ReportFileModel.DoesNotExist:
            messages.error(request, "未找到对应的报表记录")
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

        # 处理文件重命名
        # 1. 获取原文件完整路径和扩展名
        old_file_path = os.path.join(settings.MEDIA_ROOT, report_style)
        file_ext = os.path.splitext(report_style)[1]  # 获取扩展名（如 .docx）

        # 2. 构建新文件名（保留扩展名）
        # 确保新文件名不包含路径分隔符，避免安全问题
        new_filename = f"{new_report_name}{file_ext}".replace('/', '').replace('\\', '')

        # 3. 构建新文件完整路径（保持原目录结构）
        old_file_dir = os.path.dirname(old_file_path)
        new_file_path = os.path.join(old_file_dir, new_filename)

        try:
            # 4. 重命名文件系统中的文件
            if os.path.exists(old_file_path):
                os.rename(old_file_path, new_file_path)
            else:
                messages.warning(request, "原文件不存在，仅更新数据库记录")

            # 5. 更新数据库记录（report_file 存储相对路径）
            # 计算新的相对路径（相对于 MEDIA_ROOT）
            new_relative_path = os.path.relpath(new_file_path, settings.MEDIA_ROOT)
            report_file.report_name = new_filename  # 存储不带扩展名的名称（或根据需求调整）
            report_file.report_file = new_relative_path.replace('\\','/')  # 更新 FileField 路径
            report_file.save()

            messages.success(request, f"报表名称已更新为：{new_report_name}")

        except Exception as e:
            messages.error(request, f"修改失败：{str(e)}")

        # 重定向回原页面
        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

    # 非POST请求处理
    messages.error(request, "请通过表单提交修改请求")
    return HttpResponseRedirect('/')
@csrf_exempt
def reportDesignPost(request):
    report_content = request.read()

    report = request.GET.get('report')
    save_path = os.path.join(settings.MEDIA_ROOT, '/'.join(report.split('/')[2:]))
    with open(save_path, 'wb') as f:
        f.write(report_content)
    return HttpResponse('成功')
@csrf_exempt
def printSimpleData(request):
    context={
        "Detail": [],
        'Master': {'username':request.user.username}
    }
    model=request.GET.get('model')
    type=request.GET.get('report_type')
    app_name, model_name=model.split('.')
    ModelClass = apps.get_model(app_name, model_name)

    if type=='1': #主包表
        # 获取数据并转换为字典
        items = ModelClass.objects.all()[:5]

        for item in items:
            item_dict = model_to_dict(item)
            # 处理日期时间类型（转换为字符串）
            for key, value in item_dict.items():
                if isinstance(value, timezone.datetime):
                    item_dict[key] = value.strftime('%Y-%m-%d %H:%M:%S')
            context['Detail'].append(item_dict)
    else:
        # 获取数据并转换为字典
        items = ModelClass.objects.first()


        # 处理日期时间类型（转换为字符串）
        for key, value in items.items():
            if isinstance(value, timezone.datetime):
                context['Master'][key] = value.strftime('%Y-%m-%d %H:%M:%S')
            else:
                context['Master'][key] = value

    return JsonResponse(context)





